#include "activation_thread_kms.h"
#include <QDebug>
#include <QMessageBox>

int activation_thread_kms::broadcast_cnt = 0;

activation_thread_kms::activation_thread_kms(QObject *parent) : QThread(parent)
{
    this->udpSocket = socketmanager::GetInstance()->get_udpSocket();
    this->tcpSocket = socketmanager::GetInstance()->get_tcpSocket();

    this->timer = new QTimer(this);
    this->isStarted = false;
    this->port = 7070;
    this->udp_send_info = "";
    this->tcp_send_info = "";
    this->server_dns = "";
    this->server_ip = "";
    this->conconf = new getconnectconfig;

    connect(this->timer, SIGNAL(timeout()), this, SLOT(sendudp()));
    connect(this->udpSocket, SIGNAL(readyRead()),this, SLOT(receiveudp()));

    QSettings settings("/usr/share/kylin-activation/activation_conf.ini", QSettings::IniFormat);
    QString cvd = settings.value("MODE_Activation/cloud_virtual_desktop").toString();
    if ("true"==cvd) {
        qDebug()<<"Cloud Desktop Activation Mode ...";
        this->isCloudPlatform = true;
    } else {
        qDebug()<<"Non cloud desktop activation mode ...";
        this->isCloudPlatform = false;
    }
}

// 用于线程自动收集信息并加密后发送给服务端
void activation_thread_kms::run()
{
    QString settings_register, settings_status, settings_serial, settings_harddisk_id, settings_system_uuid, settings_interface_mac, settings_active_state;
    QString now_register, now_status, now_serial, now_harddisk_id, now_system_uuid, now_interface_mac;
    gchar * input_serial;
    char * send_allinfo;
    int flag = 0;
    QString active_st = status_date(), allinfo, ld = "0";
    QString config_path = QDir::homePath() + "/.config/activation_conf.ini";
    QFileInfo file(config_path);
    QByteArray ba;
    int ret;
    unsigned int out_size = 0;
    char buffer[4096] = {0};
    memset(buffer, 0, sizeof(buffer));

    if(file.exists()==false)
        QFile::copy("/etc/kylin-activation/activation_conf.ini", config_path);

//    if(active_st != "")
//    {

        QSettings settings(config_path, QSettings::IniFormat);
        settings.setIniCodec(QTextCodec::codecForName("utf-8"));
        ba = settings.value("Sent_Server/register").toByteArray();
        settings_register =QString::fromLatin1(QByteArray::fromBase64(ba));

        ba = settings.value("Sent_Server/status").toByteArray();
        settings_status =QString::fromLatin1( QByteArray::fromBase64(ba));

        ba = settings.value("Sent_Server/serial").toByteArray();
        settings_serial =QString::fromLatin1( QByteArray::fromBase64(ba));

        ba = settings.value("Sent_Server/harddisk_id").toByteArray();
        settings_harddisk_id =QString::fromLatin1( QByteArray::fromBase64(ba));

        ba = settings.value("Sent_Server/system_uuid").toByteArray();
        settings_system_uuid =QString::fromLatin1( QByteArray::fromBase64(ba));

        ba = settings.value("Sent_Server/interface_mac").toByteArray();
        settings_interface_mac =QString::fromLatin1( QByteArray::fromBase64(ba));
    
        ba = settings.value("Sent_Server/current_active").toByteArray();
        settings_active_state =QString::fromLatin1( QByteArray::fromBase64(ba));
//        qDebug()<< "wb0" << settings_register << settings_status << settings_serial << settings_harddisk_id << settings_system_uuid << settings_interface_mac;

        now_serial = get_serial_number();

        if(now_serial.toInt() < 10000000 && now_serial.toInt() > 999999)
            now_serial = ld + now_serial;
        ba = now_serial.toLatin1();
        input_serial = ba.data();

        now_register = new_register_number(input_serial)->at(0);
        now_status = QString::number(status_code());
        if(now_status == "0" || trial_status()==1)
            now_status = "1";
        now_harddisk_id = get_harddisk_id();
        now_system_uuid = get_system_uuid();
        now_interface_mac = get_interface_mac();

        if (isCloudPlatform) {
        settings.setValue("/MODE_Activation/cloud_virtual_desktop", "true");
        } else {
            settings.setValue("/MODE_Activation/cloud_virtual_desktop", "false");
        }
        settings.sync();

//        qDebug() << "wb1"<< now_register << now_status << now_serial << now_harddisk_id << now_system_uuid << now_interface_mac;
        settings_active_state = " ";
        settings.setValue("Active_State/current_active",  QString(settings_active_state));
        if(settings_register != now_register)
        {
            flag = 1;
            ba = now_register.toLatin1();
            settings.setValue("/Sent_Server/register", ba.toBase64());
        }

        if(settings_status != now_status)
        {
            flag = 1;
            ba = now_status.toLatin1();
            settings.setValue("/Sent_Server/status",  ba.toBase64());
        }

        if(settings_serial != now_serial)
        {
            flag = 1;
            ba = now_serial.toLatin1();
            settings.setValue("/Sent_Server/serial",  ba.toBase64());
        }

        if(settings_harddisk_id != now_harddisk_id)
        {
            flag = 1;
            ba = now_harddisk_id.toLatin1();
            settings.setValue("/Sent_Server/harddisk_id",  ba.toBase64());
        }

        if(settings_system_uuid != now_system_uuid)
        {
            flag = 1;
            ba = now_system_uuid.toLatin1();
            settings.setValue("/Sent_Server/system_uuid",  ba.toBase64());
        }

        if(settings_interface_mac != now_interface_mac)
        {
            flag = 1;
            ba = now_interface_mac.toLatin1();
            settings.setValue("/Sent_Server/interface_mac",  ba.toBase64());
        }
        settings.sync();
        if(flag == 1)
        {
            allinfo = now_serial + "'" + now_register + "'" + now_system_uuid + "'" + now_interface_mac + "'" + now_harddisk_id + "'";
            if(now_status == "1")
                allinfo = allinfo + "T";
            else
                allinfo = allinfo + "F";
            qDebug() << "all_info：" << allinfo;
            QByteArray ba = allinfo.toLatin1();
            send_allinfo = ba.data();
            ret = encrypt_hardware_info(send_allinfo, strlen(send_allinfo), (unsigned char*)buffer, &out_size);
            allinfo = QString::fromUtf8(buffer);
            emit activation_post_signal( allinfo);
        }

//    }
}

void activation_thread_kms::refresh_activation_conf()
{
    QString settings_register, settings_status, settings_serial, settings_harddisk_id, settings_system_uuid, settings_interface_mac, settings_active_state;
    QString now_register, now_status, now_serial, now_harddisk_id, now_system_uuid, now_interface_mac;
    gchar * input_serial;
    int flag = 0;
    QString ld = "0";
    QString config_path = QDir::homePath() + "/.config/activation_conf.ini";
    QFileInfo file(config_path);
    QByteArray ba;
    char buffer[4096] = {0};
    memset(buffer, 0, sizeof(buffer));

    if(file.exists()==false)
        QFile::copy("/usr/share/kylin-activation/activation_conf.ini", config_path);

    QSettings settings(config_path, QSettings::IniFormat);
    settings.setIniCodec(QTextCodec::codecForName("utf-8"));
    ba = settings.value("Sent_Server/register").toByteArray();
    settings_register =QString::fromLatin1(QByteArray::fromBase64(ba));

    ba = settings.value("Sent_Server/status").toByteArray();
    settings_status =QString::fromLatin1( QByteArray::fromBase64(ba));

    ba = settings.value("Sent_Server/serial").toByteArray();
    settings_serial =QString::fromLatin1( QByteArray::fromBase64(ba));

    ba = settings.value("Sent_Server/harddisk_id").toByteArray();
    settings_harddisk_id =QString::fromLatin1( QByteArray::fromBase64(ba));

    ba = settings.value("Sent_Server/system_uuid").toByteArray();
    settings_system_uuid =QString::fromLatin1( QByteArray::fromBase64(ba));

    ba = settings.value("Sent_Server/interface_mac").toByteArray();
    settings_interface_mac =QString::fromLatin1( QByteArray::fromBase64(ba));

    now_serial = get_serial_number();

    if(now_serial.toInt() < 10000000 && now_serial.toInt() > 999999)
        now_serial = ld + now_serial;
    ba = now_serial.toLatin1();
    input_serial = ba.data();

    now_register = new_register_number(input_serial)->at(0);
    now_status = QString::number(status_code());
    if(now_status == "0" || trial_status()==1)
        now_status = "1";
    now_harddisk_id = get_harddisk_id();
    now_system_uuid = get_system_uuid();
    now_interface_mac = get_interface_mac();

    if(settings_register != now_register)
    {
        flag = 1;
        ba = now_register.toLatin1();
        settings.setValue("/Sent_Server/register", ba.toBase64());
    }

    if(settings_status != now_status)
    {
        flag = 1;
        ba = now_status.toLatin1();
        settings.setValue("/Sent_Server/status",  ba.toBase64());
    }

    if(settings_serial != now_serial)
    {
        flag = 1;
        ba = now_serial.toLatin1();
        settings.setValue("/Sent_Server/serial",  ba.toBase64());
    }

    if(settings_harddisk_id != now_harddisk_id)
    {
        flag = 1;
        ba = now_harddisk_id.toLatin1();
        settings.setValue("/Sent_Server/harddisk_id",  ba.toBase64());
    }

    if(settings_system_uuid != now_system_uuid)
    {
        flag = 1;
        ba = now_system_uuid.toLatin1();
        settings.setValue("/Sent_Server/system_uuid",  ba.toBase64());
    }

    if(settings_interface_mac != now_interface_mac)
    {
        flag = 1;
        ba = now_interface_mac.toLatin1();
        settings.setValue("/Sent_Server/interface_mac",  ba.toBase64());
    }
    settings.sync();
}

void activation_thread_kms::generate_udp_send_info()
{
    QString hdinfo, serial_number;
    hdinfo = get_encrypted_hardware_info();
    serial_number = get_serial_number();
    this->udp_send_info = "KY-ACTIVATE:" + serial_number + ":" + hdinfo;
}

void activation_thread_kms::receiveudp()
{
    char buf[1024]={0};
    quint16 report;
    QString str,strbuf;
    QStringList strsplit;
    QStringList *strlist = NULL;
    QByteArray ba;
    char buffer[4096] = {0};
    memset(buffer, 0, sizeof(buffer));
    qint64 len = this->udpSocket->readDatagram(buf,sizeof(buf),&this->hostAddress,&report);
    if(len > 0) {
        str = QString::fromUtf8(buf);
        qDebug() << "receiveudp" << str;
        strsplit = str.split(":");
        if(strsplit.at(0) == "KY-ACTIVATE-SERIAL" && strsplit.size() == 2) {
            //保存udp解析的serverip
            QString config_path = QDir::homePath() + "/.config/activation_conf.ini", hostaddr;
            QByteArray ba;
            QSettings settings(config_path, QSettings::IniFormat);
            ba = QHostAddress(this->hostAddress.toIPv4Address()).toString().toLatin1();
            hostaddr = ba;
            settings.setValue("KMS_Activation/hostaddr", hostaddr);
            settings.sync();

            this->host_port = report;
            strbuf = strsplit.at(1);
            ba = strbuf.toLatin1();
            strlist = new_register_number(ba.data());
            this->register_number = strlist->at(0);
            this->serial_number = strsplit.at(1);

            connect(this->tcpSocket,SIGNAL(readyRead()),this, SLOT(receivetcp()));
            if (isCloudPlatform)
                refresh_activation_profile();
            refresh_activation_code(this->serial_number);
        }
    }
    return;
}

void activation_thread_kms::refresh_activation_code(QString serial_number) {
    QByteArray ba;
    QString now_harddisk_id,now_system_uuid,now_interface_mac,allinfo;
    int ret;
    unsigned int out_size = 0;
    char * send_allinfo;
    char buffer[4096] = {0};
    memset(buffer, 0, sizeof(buffer));

    now_harddisk_id = get_harddisk_id();
    now_system_uuid = get_system_uuid();
    now_interface_mac = get_interface_mac();
    allinfo = now_system_uuid + "'" + now_interface_mac + "'" + now_harddisk_id;
    ba = allinfo.toLatin1();
    send_allinfo = ba.data();
    ret = encrypt_hardware_info(send_allinfo, strlen(send_allinfo), (unsigned char*)buffer, &out_size);
    allinfo = QString::fromUtf8(buffer);

    this->tcp_send_info = "KY-ACTIVATE:" + serial_number + ":" + this->register_number + ":" + allinfo
            + ":"+QString::fromLocal8Bit(get_service_tag().toLocal8Bit().toBase64())
            + ":"+QString::fromLocal8Bit(get_vendor().toLocal8Bit().toBase64())
            + ":"+QString::fromLocal8Bit(get_model().toLocal8Bit().toBase64());
    qDebug()<<"tcp send info:"<<this->tcp_send_info<<", tcpSocket->localPort: "<<this->tcpSocket->localPort();

    this->tcpSocket->connectToHost(this->hostAddress,this->port);
    if(!this->tcpSocket->waitForConnected(15000)) {
        qDebug() << "Can't connect to host: "<<this->tcpSocket->error();
        return ;
    }
    this->tcpSocket->write(this->tcp_send_info.toLatin1());
    this->tcpSocket->flush();
}

void activation_thread_kms::refresh_activation_profile()
{
    QString tcp_send_info = "KY-CONFIG";

    if (this->tcpSocket->state()!=QAbstractSocket::UnconnectedState)
        this->tcpSocket->disconnectFromHost();
    this->tcpSocket = socketmanager::GetInstance()->get_tcpSocket();

    qDebug()<<"server_dns: "<<this->server_dns<<"server ip:"<<this->server_ip<<", host_port: "<<this->port<<", host_addr: "<<QHostAddress(this->hostAddress.toIPv4Address()).toString();
    qDebug()<<"TCP send_info: "<<tcp_send_info;
    
    if (this->server_ip != "")
        this->tcpSocket->connectToHost(QHostAddress(this->server_ip),this->port);
    else
        this->tcpSocket->connectToHost(this->hostAddress,this->port);
    
    if(!this->tcpSocket->waitForConnected(3000)) {
        qWarning()<<"Refresh activation profile[Connect] failed.";
        return ;
    }

    this->tcpSocket->write(tcp_send_info.toLatin1());
    this->tcpSocket->flush();
    this->tcpSocket->waitForBytesWritten();

    // 等待接收数据
    if (!this->tcpSocket->waitForReadyRead(3000)) {
        qWarning()<<"Refresh activation profile[Recv] failed.";
    }
}

void activation_thread_kms::receivetcp()
{
    QByteArray buf;
    QString recstr,strbuf;
    QStringList strsplit;
    QByteArray ba, ba_serial;

    gint activation = 1;
    qDebug() << "receivetcp 0 kms";

    buf = this->tcpSocket->readAll();
    if(!buf.isEmpty()) {
        recstr = QString(buf);
        qDebug() << "receivetcp 1" << recstr;
        strsplit = recstr.split(":");
        if(strsplit.at(0) == "KY-ACTIVATE-KEY" && strsplit.size() == 3) {
            qDebug() << "receivetcp 22, "<<strsplit.at(2)<<strsplit.at(1)<< this->serial_number;
            strbuf = strsplit.at(2);
            ba = strbuf.toLocal8Bit();

            QByteArray base64by = ba.fromBase64(ba);
            QString base64str = QString::fromLocal8Bit(base64by);
            QString config_path = QDir::homePath() + "/.config/activation_conf.ini";
            QSettings settings(config_path, QSettings::IniFormat);

            ba = base64str.toLocal8Bit();

            set_customer(ba.data());

            strbuf = strsplit.at(1);
            ba = strbuf.toLatin1();

            ba_serial = this->serial_number.toLatin1();

            activation = new_active_code(ba_serial.data(),ba.data());
            if(activation==0) {
                this->current_active = "true";
                ba = this->current_active.toLatin1();
                settings.setValue("/Active_State/current_active",  ba.toBase64());
                broadcast_cnt = 0;
                qDebug()<<"Activation success! "<<broadcast_cnt<<endl;
            } else
                qDebug() <<"Activation result:"<<activation<<endl;

            emit activation_message_signal(activation);
            this->tcpSocket->disconnectFromHost();

            settings.setValue("/Active_State/current_active",  QString(this->current_active));
            settings.sync();

            if (!isCloudPlatform) {
                exit_service();
                qApp->exit(0);
            }
            disconnect(this->tcpSocket,SIGNAL(readyRead()),this, SLOT(receivetcp()));
        } else if (strsplit.at(0) == "KY-ACTIVATE-ERROR") {
            qDebug()<<"activation error: "<<strsplit.at(1);
            this->tcpSocket->disconnectFromHost();
            if (!isCloudPlatform) {
                exit_service();
                qApp->exit(0);
            }
        }  else if(strsplit.at(0) == "KY-CONFIG-CONTENT") {
            QString orig_data = strsplit.at(1), item, section, key, value;
            QStringList profile;
            QString profile_path = QDir::homePath()+"/.config/kylin-activation/activation_profile.ini";
            QSettings settings(profile_path, QSettings::IniFormat);

            profile = orig_data.split("\n");
            qDebug() <<"Get activation profile:"<<profile;
            QStringListIterator strIterator(profile);
            while (strIterator.hasNext()) {
                item = strIterator.next();
                if (item.contains("[") && item.contains("]")) {
                    section = item.remove('[').remove(']');
                } else if (item.contains("=")) {
                    key = item.split("=")[0];
                    value = item.split("=")[1];
                    settings.setValue(section+"/"+key, value);
                }
            }
            settings.sync();

            this->tcpSocket->disconnectFromHost();
        }
    }
}


void activation_thread_kms::sendudp()
{
    bool current_state;
    int length=0;
    int retry_count=0;
    broadcast_cnt += 1;
    int active_st = status_code();
    int activation_interval=0,offset_value=0,initial_interval=0;
    this->timer->stop();
    static int activation_interval_total = 0;

    refresh_activation_conf();
    generate_udp_send_info();

    qDebug()<<"server dns:"<<this->server_dns<<"server ip:"<<this->server_ip<<" ."<<broadcast_cnt;
    qDebug()<<"send udp:"<<this->udp_send_info;

    retry_count = this->conconf->get_connectconf_value("Active_State", "retry_count").toInt();
    retry_count = retry_count>=0?retry_count:10;//默认10次
    offset_value = this->conconf->get_connectconf_value("Inactive_State", "offset_value_sec").toInt();
    offset_value = offset_value>0?offset_value:10;//默认10s
    initial_interval = this->conconf->get_connectconf_value("Inactive_State", "initial_interval_sec").toInt();
    initial_interval = initial_interval>=0?initial_interval:10;//默认10s
    current_state = this->conconf->get_current_active_state();

    if (isCloudPlatform) {
        //重置定时器时间
        if (current_state) {
            activation_interval = this->conconf->get_connectconf_value("Active_State", "activation_interval_sec").toInt();
            qDebug()<<"activation interval: "<<activation_interval;
        } else { //生成随机时间
            activation_interval = this->conconf->generate_random_time(initial_interval, offset_value);
        }

        this->timer->setInterval(activation_interval*1000);
        activation_interval_total+=activation_interval;
        if(broadcast_cnt >= retry_count) {
            //删除激活文件
            if(remove_activation_file())
                exit_service();
            //记录无法与服务端建立连接的状态
            QString config_path = QDir::homePath() + "/.config/activation_conf.ini";
            QSettings settings(config_path, QSettings::IniFormat);
            this->current_active = "false";
            broadcast_cnt = 0;
            settings.setValue("/Active_State/current_active",  QString(this->current_active));
        }

        if(this->server_ip != "")
            length = this->udpSocket->writeDatagram(this->udp_send_info.toLatin1(),\
                                                    this->udp_send_info.length(),\
                                                    QHostAddress(this->server_ip),\
                                                    this->port);
        else 
            length = this->udpSocket->writeDatagram(this->udp_send_info.toLatin1(),\
                                                    this->udp_send_info.length(),\
                                                    QHostAddress::Broadcast,\
                                                    this->port);

    } else {
        this->timer->setInterval(4*1000);
        if(active_st == 1) {
            QFile activation_file("/etc/.kyactivation");
            if(activation_file.exists() && activation_file.open(QIODevice::ReadOnly | QIODevice::Text)) {
                QTextStream aStream(&activation_file);
                QString kyStr = aStream.readAll();
                QString kyLastTwo = kyStr.right(2);
                QString targetStr = "IO10";
                if(!targetStr.contains(kyLastTwo[0], Qt::CaseSensitive) && !targetStr.contains(kyLastTwo[1], Qt::CaseSensitive))  {
                    qDebug()<<"The system has been activated!";
                    exit_service();
                    qApp->exit(0);
                    return ;
                }
            }
        }

        if(broadcast_cnt >= 5)
        {
            this->timer->stop();
            bool _current_activate = false;
            broadcast_cnt = 0;
            QFile activation_file("/etc/.kyactivation");
            if(activation_file.exists() && activation_file.open(QIODevice::ReadOnly | QIODevice::Text))  {
                QTextStream aStream(&activation_file);
                QString kyStr = aStream.readAll();
                QString kyLastTwo = kyStr.right(2);
                QString targetStr = "IO10";
                if(targetStr.contains(kyLastTwo[0], Qt::CaseSensitive) || targetStr.contains(kyLastTwo[1], Qt::CaseSensitive))
                {
                    if(active_st == 0) {
                        if(remove_activation_file())
                            exit_service();
                    }
                }
            }
            //记录无法与服务端建立连接的状态
            QByteArray ba;
            QString config_path = QDir::homePath() + "/.config/activation_conf.ini";
            QSettings settings(config_path, QSettings::IniFormat);
            this->current_active = "false";
            ba = this->current_active.toLatin1();
            settings.setValue("/Active_State/current_active",  ba.toBase64());
            exit_service();
            qApp->exit(0);
            return ;
        }

        if(this->server_ip != "")
            length = this->udpSocket->writeDatagram(this->udp_send_info.toLatin1(),\
                                                    this->udp_send_info.length(),\
                                                    QHostAddress(this->server_ip),\
                                                    this->port);
        else
            length = this->udpSocket->writeDatagram(this->udp_send_info.toLatin1(),\
                                                    this->udp_send_info.length(),\
                                                    QHostAddress::Broadcast,\
                                                    this->port);
    }

    this->timer->start();
}

void activation_thread_kms::init_udpinfo()
{
    int initial_interval;
    this->server_dns.clear();

    //初始化配置文件
    init_activation_profile();

    QSettings settings("/etc/kylin-activation/activation_conf.ini", QSettings::IniFormat);
    this->server_dns = settings.value("KMS_Activation/ServerIp").toString();

    this->initial_interval = this->conconf->get_connectconf_value("Inactive_State", "initial_interval_sec");
    initial_interval = this->initial_interval.toInt();
    initial_interval = initial_interval>=0?initial_interval:10;//默认10s

    if (!isCloudPlatform) {
        initial_interval = 4;
    }

    //查找服务端ip
    QHostInfo::lookupHost(this->server_dns,this, [=](QHostInfo host)
    {
        QString hdinfo, serial_number;
        hdinfo = get_encrypted_hardware_info();
        serial_number = get_serial_number();
        if(host.error()!=QHostInfo::NoError)
        {
            qDebug() << "Lookup failed:" << host.errorString();
            this->udp_send_info = "KY-ACTIVATE:" + serial_number + ":" + hdinfo;
            this->timer->start(initial_interval*10);
            return;
        }

        Q_FOREACH(QHostAddress address, host.addresses())
        {
            qDebug() << "Found address:" << address.toString();
            this->server_ip=address.toString();
            this->udp_send_info = "KY-ACTIVATE:" + serial_number + ":" + hdinfo;
            this->timer->start(initial_interval*10);
            break;
        }
    });
}

void activation_thread_kms::init_activation_profile()
{
    QString profile_path = QDir::homePath()+"/.config/kylin-activation/activation_profile.ini";
    QFileInfo fileInfo(profile_path);
    if (!fileInfo.exists()) {
        qInfo()<<"The activation-profile isn't exists.";
        QSettings settings(profile_path, QSettings::IniFormat);
        settings.setValue("/Active_State/activation_interval_sec", "60");
        settings.setValue("/Active_State/retry_count", "10");
        settings.setValue("/Inactive_State/initial_interval_sec", "10");
        settings.setValue("/Inactive_State/offset_value_sec", "10");
        settings.sync();
    }
}

void activation_thread_kms::oemActivate()
{
    if(check_oem())
    {
        QString url=QString("https://wx.kylinos.cn/api/oem_activation.json?f=%1&v=%2&m=%3&s=%4")
                .arg(get_serial_number())
                .arg(get_vendor())
                .arg(get_model())
                .arg(get_service_tag());
        QNetworkRequest request;
        QNetworkAccessManager* naManager = new QNetworkAccessManager(this);
        request.setUrl(QUrl(QUrl::toPercentEncoding(url,"/:&%=?"," ")));
        qDebug()<<"OEM URL:"<<QUrl::toPercentEncoding(url,"/:&%=?"," ");
        naManager->get(request);
        connect(naManager,&QNetworkAccessManager::finished,this,[=](QNetworkReply* reply){
            QNetworkReply::NetworkError err = reply->error();
            if(err == QNetworkReply::NoError)
            {
                QJsonParseError error;
                QJsonDocument readDoc=QJsonDocument::fromJson(reply->readAll(),&error);
                if(!readDoc.isNull() && error.error==QJsonParseError::NoError)
                {
                    if(0==readDoc.object().value("errcode").toInt())
                    {
                        QJsonObject obj=readDoc.object().value("data").toObject();
                        if(!obj.value("SERIAL").toString().isEmpty() && !obj.value("KEY").toString().isEmpty())
                            new_active_code(obj.value("SERIAL").toString().toLocal8Bit().data(),obj.value("KEY").toString().remove("-").toLocal8Bit().data());
                    }
                }
            }
            reply->deleteLater();
        });
    }
}
